#pragma once
#include <list>
#include <windows.h>
#include "PDFCreator.h"
#include "FilerFrogElement.h"
#include "TextFileWriter.h"
#include "ANSITextFileWriter.h"
#include <gdiplus.h>

#define ENCRYPTION_EXTENSION L"ffenc"
#define SPLIT_EXTENSION L"ffs"
#define UtilsObjCreate GetSystemTime

typedef wchar_t ucs4_t;

enum ACTION_TYPE{
	EXTRACT_FROM_FOLDER,
	EXTRACT_TO_FOLDER,
	COPY,
	MOVE,
	MAKE_LIST,
	RESIZE_IMAGE,
	DELETE_ZERO,
	SPLIT,
	JOIN,
	PDF_ALBUM,
	ENCRYPT,
	DECRYPT,
	RENAME,
	UNHIDE,
	LOGO_ON_IMAGES,
	TOUCH_FILES
};

enum FRRESPONSE_ENUM{
	SUCCESS,
	FAIL_UNEXPECTED_ERROR,
	//FAIL_DIRECTORY_EXISTS,
	FAIL_DIRECTORY_DOESNT_EXIST,
	//FAIL_FILE_EXISTS,
	FAIL_SOME_FILES_FAILED,
	FAIL_FILE_OPEN,
	//FAIL_OPEN_ERROR,
	FAIL_WRONG_PASSWORD,
	FAIL_USER_DECIDED,
	FAIL_WRONG_SPLIT_SIZE,
	FAIL_COUNT,
	FAIL_WRONG_NUM_OF_FILES,
	FAIL_SOME_FILES_WRONG_KIND,
	FAIL_PATH_DUPLICATION,
	FAIL_WRONG_SIZE_OF_LIST,
	FAIL_WRONG_FILE_SELECTION,
	FAIL_PDF_FAIL,
	FAIL_IS_DIR_NOT_FILE,
	FAIL_IS_FILE_NOT_DIR
};

enum IMAGE_LOC{
	TOP_LEFT,
	TOP_CENTER,
	TOP_RIGHT,
	MIDDLE_LEFT,
	MIDDLE_CENTER,
	MIDDLE_RIGHT,
	BOTTOM_LEFT,
	BOTTOM_CENTER,
	BOTTOM_RIGHT
};

struct FRRESPONSE{
public:
	FRRESPONSE_ENUM Kind;
	ACTION_TYPE Type;
	wstring Text;
	int NumOfSucceeded;
	int NumOfFailed;
	list<wstring> NewFiles;

	FRRESPONSE(){}

	~FRRESPONSE(){}
};

class FilesRefactor : FilerFrogElement
{
private:
	void *m_CallbackObject;
	void (*m_ReportProgressFunc)(void* pt2Object, int progress, bool closeProgressWindow);
	void ReportProgress(int progress, bool closeProgressWindow);

	void EncryptList(FRRESPONSE& res, std::list<wstring> &filesList,  
		const wstring& password, float progress, float pInterval);
	void DecryptList(FRRESPONSE& res, std::list<wstring> &filesList, const wstring& password,
		float progress, float pInterval);
	void UnHideFile(FRRESPONSE& res, wstring& fileName);
	void writeFolderContent(FRRESPONSE& res, TextFileWriter& fileWriter, const wstring& folder, bool isDetailed, bool fullPath, int level, bool indentSubfolders);
	void MakeListOfFilesHTML(FRRESPONSE& res, std::list<wstring> &filesList, const wstring &fileName, bool isDetailed, 
		bool fullPath, bool drillDown, bool indentSubfolders);
	void writeFolderContentHTML(FRRESPONSE& res, TextFileWriter& fileWriter, const wstring& folder, bool isDetailed, bool fullPath, 
		int level, bool indentSubfolders);
public:
	FilesRefactor(void (*pReportProgressFunc)(void* pt2Object, int progress, bool closeProgressWindow),
					int (*pFrogMessageBoxFunc)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType),
					void* callbackObject);
	~FilesRefactor();

	void SetParentWindow(HWND parent);

	void ExtractFilesFromFolder(FRRESPONSE& res, const wstring& folderPath);
	void ExtractFilesFromMultipleFolders(FRRESPONSE& res, list<wstring>& foldersPaths);
	void ExtractFilesToFolder(FRRESPONSE& res, list<wstring>& filesList, const wstring& currentFolder, const wstring& folderName);
	void MoveFilesUp(FRRESPONSE& res, list<wstring>& filesList);
	void CopyFiles(FRRESPONSE& res, list<wstring>& filesList, const wstring& destFolder);
	void MoveFiles(FRRESPONSE& res, list<wstring>& filesList, const wstring& destFolder);
	void MakeListOfFiles(FRRESPONSE& res, list<wstring>& filesList, const wstring &fileName, bool isDetailed, 
		bool fullPath, bool drillDown = false, bool indentSubfolders = false, bool asHTML = false);
	
	void ShrinkImageFilesByPercent(FRRESPONSE& res, list<wstring>& filesList, double shrinkBy, int quality, bool saveJPG, const wstring& wrapFolder = L"");
	void ShrinkImageFilesBySize(FRRESPONSE& res, list<wstring>& filesList, int width, int height, int quality, bool saveJPG, const wstring& wrapFolder = L"");
	
	void DeleteZeroFiles(FRRESPONSE& res, list<wstring>& filesList);
	
	void SplitFile(FRRESPONSE& res, const wstring& file, size_t  size);
	void JoinFiles(FRRESPONSE& res, list<wstring>& filesList, bool flexible=false);
	
	// FRRESPONSE DeleteDuplicates();
	// FRRESPONSE GeneratePowerPointSlideShow();
	
	void GeneratePdf(FRRESPONSE& res, PDFFile& pdfFile, bool pagesFlat=false);
	
	void Encrypt(FRRESPONSE& res, list<wstring>& filesList, const wstring& password, bool deleteFile);
	void Decrypt(FRRESPONSE& res, list<wstring>& filesList, const wstring& password);

	void RenameFilesFindReplace(FRRESPONSE& res, list<wstring>& filesList, const wstring& search, const wstring& replace);
	void RenameFilesAutoNumbering(FRRESPONSE& res, list<wstring>& filesList, int start);
	void RenameFilesAlphabetize(FRRESPONSE& res, list<wstring>& filesList, bool start=false);
	void RenameFilesAppend(FRRESPONSE& res, list<wstring>& filesList, const wstring& prefix, const wstring& postfix);
	void RenameFilesAutoNumberingAppend(FRRESPONSE& res, list<wstring>& filesList, int start, const wstring& prefix, const wstring& postfix);
	void RenameFilesAlphabetizeAppend(FRRESPONSE& res, list<wstring>& filesList, const wstring& prefix, const wstring& postfix);
	void RenameFilesMakeSameName(FRRESPONSE& res, list<wstring>& filesList, const wstring& anchor);
	void RenameFilesTruncate(FRRESPONSE& res, list<wstring>& filesList, int numberOfChars, bool truncFromBegining, bool includeFileExtension);

	bool CheckFilesSameName(FRRESPONSE& res, const list<wstring>& filesList);

	void TouchFiles(FRRESPONSE& res, const list<wstring>& filesList);

	void LogoOnImages(FRRESPONSE& res, const list<wstring>& filesList, const wstring& logoPath, 
		const wstring& logoText, LOGFONTW logoFont, Gdiplus::Color fontColor,
		bool addBorder, Gdiplus::Color borderColor, 
		bool useLogoImage, IMAGE_LOC location, const wstring& wrapFolder = L"");

	void SendMail();
};
